package com.zzj.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzj.base.Result;
import com.zzj.entity.Article;
import com.zzj.entity.Like;
import com.zzj.handle.WebSocket;
import com.zzj.model.dto.QueryListDTO;
import com.zzj.model.dto.article.ArticleCreateDTO;
import com.zzj.model.dto.article.ArticleUpdateDTO;
import com.zzj.service.IArticleService;
import com.zzj.service.ILikeService;
import com.zzj.service.RedisService;
import com.zzj.utils.JWTUtil;
import com.zzj.utils.QueryUtil;
import com.zzj.utils.Utils;
import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;

import java.util.Arrays;
import java.util.List;


/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author zzj
 * @since 2023-03-16
 */
@RestController
@RequestMapping("/article")
public class ArticleController {

    @Resource
    private IArticleService articleService;
    @Resource
    private RedisService redisService;
    @Resource
    private ILikeService likeService;
    @Resource
    private WebSocket webSocket;


    @PostMapping("queryList")
    public Result queryList(
            @RequestHeader(value = "Authorization") String token,
            @RequestBody @Validated QueryListDTO in) {

        QueryWrapper<Article> queryWrapper = QueryUtil.paramsWrapper(in.getAndParams(), in.getOrParams(), in.getOrderParams());
        Page<Article> articlePage = new Page<>(in.getPageNo(), in.getPageSize());
        IPage<Article> articleIPage = articleService.getBaseMapper().selectPage(articlePage, queryWrapper);
        List<Article> articles = articleIPage.getRecords();

        String username = JWTUtil.getUsername(token);

        String likeArticleId = redisService.getLikeArticleId(username);
        if (likeArticleId != null && !likeArticleId.equals("")) {
            String[] split = likeArticleId.split(",");
            List<String> reads = Arrays.asList(split);
            List<Article> list = articles.stream()
                    .map(article -> reads.stream()
                            .filter(str -> article.getId() == Integer.parseInt(str))
                            .findFirst()
                            .map(str -> {
                                article.setIsLike(1);
                                return article;
                            }).orElse(article)).toList();
        }
        articleIPage.setRecords(articles);
        return Result.success(articleIPage);
    }

    @Transactional
    @PostMapping("id")
    public Result id(@RequestHeader(value = "Authorization") String token,
                     @RequestParam int id) {
        String username = JWTUtil.getUsername(token);
        String likeArticleId = redisService.getLikeArticleId(username);
        boolean is = Utils.stringIsContainStrSplit(likeArticleId, String.valueOf(id), ",");
        Article article = articleService.id(id);
        article.setIsLike(is ? 1 : 0);
        articleService.lambdaUpdate()
                .eq(Article::getId, id)
                .setSql("view_count = view_count + 1").update();
        return Result.success(article);
    }

    @PostMapping("create")
    public Result create(@RequestBody @Validated ArticleCreateDTO in) {
        Article article = JSONObject.parseObject(JSON.toJSONString(in), Article.class);
        articleService.save(article);
        return Result.success("创建成功");
    }

    @PostMapping("update")
    public Result update(@RequestBody @Validated ArticleUpdateDTO in) {
        articleService.update(new Article(),
                new LambdaUpdateWrapper<Article>().eq(Article::getId, in.getId())
                        .set(Article::getTitle, in.getTitle())
                        .set(Article::getContent, in.getContent())
                        .set(Article::getType, in.getType())
                        .set(Article::getCoverImage, in.getCoverImage())
                        .set(Article::getStatus, 0)
        );
        return Result.success("修改成功");
    }


    /**
     * 点赞 取消点赞
     * 未接入 推送
     *
     * @param token
     * @param id    文章ID
     * @return
     */
    @Transactional
    @PostMapping("like")
    public Result like(@RequestHeader(value = "Authorization") String token,
                       @RequestParam int id, @RequestParam String toUsername) throws IOException {
        String username = JWTUtil.getUsername(token);
        String likeArticleId = redisService.getLikeArticleId(username);
        if (likeArticleId != null) {
            List<String> likeArticleIds = Utils.stringToList(likeArticleId, ",");
            //取消点赞
            if (likeArticleIds.contains(String.valueOf(id))) {
                articleService.lambdaUpdate()
                        .eq(Article::getId, id)
                        .setSql("like_count = like_count - 1").update();
                likeArticleId = likeArticleId.replace(id + ",", "");
                Like like = likeService.findLike(id,username);
                likeService.remove(id, username);
                webSocket.sendCancelLike(toUsername, like.getId());
            } else {
                //点赞
                articleService.lambdaUpdate()
                        .eq(Article::getId, id)
                        .setSql("like_count = like_count + 1").update();
                likeArticleId += id + ",";
                Like like = likeService.save(id, 2, username, toUsername);
                webSocket.sendLike(toUsername, like.getId());
            }
            redisService.setLikeArticleId(username, likeArticleId);
        } else {
            //点赞
            redisService.setLikeArticleId(username, id + ",");
            articleService.lambdaUpdate()
                    .eq(Article::getId, id)
                    .setSql("like_count = like_count + 1").update();
            Like like = likeService.save(id, 2, username, toUsername);
            webSocket.sendLike(toUsername, like.getId());
        }
        return Result.success("操作成功");
    }

    @PostMapping("pass")
    public Result pass(@RequestParam int id) {
        articleService.setArticleStatus(id,2);
        return Result.success("操作成功");
    }

    @Transactional
    @PostMapping("fail")
    public Result fail(@RequestParam int id) {
        articleService.setArticleStatus(id,3);
        return Result.success("操作成功");
    }

    @Transactional
    @PostMapping("remove")
    public Result remove(@RequestParam int id) {
        articleService.lambdaUpdate().eq(Article::getId, id).remove();
        return Result.success("删除成功");
    }

    @Transactional
    @PostMapping("publish")
    public Result publish(@RequestParam int id) {
        articleService.setArticleStatus(id,1);
        return Result.success("发布成功");
    }
    @Transactional
    @PostMapping("cancel")
    public Result cancel(@RequestParam int id) {
        articleService.setArticleStatus(id,0);
        return Result.success("下架成功");
    }
}
